package fr.lip6.meta.ple.plextraction;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;

import artefact.generic.Artefact;
import artefact.generic.ConstructionPrimitive;
import artefact.umlClassDiagram.CreateOperation;
import artefact.umlClassDiagram.CreateOperationRefinement;
import artefact.umlClassDiagram.CreateStatement;
//import artefact.generic.export.Artefact2File;

import fr.lip6.meta.ple.constraintsextraction.ConstraintsRulesExatrction;


import fr.lip6.meta.ple.constraintsextraction.constraint.Constraint;

import fr.lip6.meta.ple.featureIdentification.DpFeatureExtraction;
import fr.lip6.meta.ple.featureIdentification.Feature;
import fr.lip6.meta.ple.featureIdentification.PlFeatureReduceLts;
import fr.lip6.meta.ple.featureIdentification.Product;
import fr.lip6.meta.ple.featureIdentification.SiFeatureExtraction;
import fr.lip6.meta.ple.generation.CompareMethode;
import fr.lip6.meta.ple.generation.fh.java.GenerateFromXmiFHJava;
import fr.lip6.meta.ple.generation.strategy.GenerationContext;
import fr.lip6.meta.ple.plextraction.config.Configuration;



public class Extract {

	public static String nameTestCase="";
	public static String[] products;

	public static void extract(ArrayList<Artefact> artfacts, String nameTestCase1, String[] products1){

		//for each artefact, create an LTS     

		nameTestCase=nameTestCase1;
		products=products1;

		//Collection<Feature> pl_features = null;

		//Product Lines Algorithm
		/*PlFeatureReduceLts plr = */new PlFeatureReduceLts();
		//LTS result = plr.transform(lts);
		try {
			//	pl_features = plr.featuresToFile("generatedFiles/"+nameTestCase+"/"+nameTestCase+"_Pl" + "_features.txt");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		//Dynamic Programming Algorithm
		/*DpFeatureExtraction dpf = */new DpFeatureExtraction();
		//Collection<Feature> dp_features = dpf.extract(artfacts);
		try {
			//	dpf.featuresToFile("generatedFiles/Bank_Dp" + "_features.txt");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		//Sets Intersection Algorithm
		SiFeatureExtraction sif = new SiFeatureExtraction();
		Collection<Feature> si_features = sif.extract(artfacts);
		try {

			sif.featuresToFile("SI" +nameTestCase+ "_features.txt");


			//sif.featuresToFile("generatedFiles/"+nameTestCase+"/"+nameTestCase+"_SI" + "_features.txt");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}



		

				Collection<Product> si_products=sif.getAllP();
		
		
				/////////////////////////////////////////////////////////////////////////////////////
		
				//rules extraction
				ConstraintsRulesExatrction re = new ConstraintsRulesExatrction();
				System.out.println("############INVOCATION##################");
				ArrayList<Constraint> rules = re.extractImplicationRules(si_features, si_products);
				// ProductLineConstruction.generateFeatureModel(si_features,rules);
				// ProductLineConstruction.construct(si_features,si_products);
				System.out.println("Generating product");
		
		
				System.out.println("RULES generated :"+rules.size());
		
		
		
				/*GnerateXmi r11=*/new GenerateFromXmiFHJava();
				CompareMethode cmp=new CompareMethode();
		
				ArrayList<Feature>	clonf = cmp.extract((ArrayList<Feature>) si_features,rules);
				ArrayList<Constraint> rules1 = cmp.getConstraints();
				System.err.println("Number of features: "+clonf.size());
		
		
		
				String folderpath = "./features/";
				File folder = new File (folderpath);
		
				folder.mkdirs();
		
				for(Feature f : clonf){
					try
					{
						FileWriter fw=new FileWriter(folderpath+f.getId());
						PrintWriter pw=new PrintWriter(fw);
						pw.println(f.toStringLines(1));
						pw.close();
		
					}
					catch(Exception e)
					{
		
						System.err.println(e.getMessage());
					}
		
				}
				ArrayList<Constraint> rrr=ConstraintsRulesExatrction.normaLizertheConrtaints(rules1);
		
				//
				// Gestion of Java extension output method (FeatureHouse, AspectJ, ...)
				// -->
				GenerationContext genContext = Configuration.getInstance().getGenerationContext();
		
				genContext.setProducts(si_products);
		
				switch(Configuration.getInstance().getExtensionType()) {
				case AJ:
					genContext.construct(clonf, si_products); // (1)
					genContext.generateFeatureModel(clonf, rrr); // (2)
					break;
				default:
					genContext.generateFeatureModel(clonf, rrr);
					genContext.construct(clonf, si_products);
					break;
				}
				// <--
				// Gestion of Java extension output method (FeatureHouse, AspectJ, ...)
				//
		
				sif.features=clonf;
		
		
		
		
				try {
		
		
		
		
					sif.featuresToFile("generatedFiles/"+nameTestCase+"/"+nameTestCase+"_SI" + "_features.txt");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}



	}


	@SuppressWarnings("unused")
	private static boolean areEquivalent(Collection<Feature> f1, Collection<Feature> f2) {
		if (f1.size() != f2.size()) return false;
		for (Feature f: f1)
			if (f.getEquivalent(f2) == null) return false;
		return true;
	}





}
